'''
Created on Apr 24, 2009

@author: utena
'''

# file:///C|/Programming/QC Try 1/pandoras-book/scripts/localTelnet.xml

from java.awt import Dimension, BorderLayout, Font
from java.awt.event import ActionListener
from javax.jms import Message, MessageListener
from javax.swing import JFrame, JEditorPane, JScrollPane, JTextField, Timer, JButton, JTextPane
from javax.swing.event import InternalFrameListener
from java.io import BufferedReader, PrintStream, InputStreamReader
from javax.swing.text import Style, StyleConstants, StyleContext

import java.net.Socket as Socket
import java.util.HashMap as Map
import java.util.UUID as UUID
import java.util.regex.Pattern as Pattern

class SwingTest(object):
    '''
    classdocs
    '''
    
    class TelWindowListener(InternalFrameListener):
        def __init__(self, app):
            self.app = app
        def internalFrameClosing(self, act):
            if self.app.telnetchetimer:
                self.app.telnetchetimer.stop()
            if self.app.sock:
                self.app.sock.close()
                
        def internalFrameClosed(self, act):
            pass
        
        def internalFrameActivated(self, act):
            pass
                
        def internalFrameDeactivated(self, act):
            pass
        
        def internalFrameDeiconified(self, act):
            pass
        
        def internalFrameIconified(self, act):
            pass
        
        def internalFrameOpened(self, act):
            pass

    class SendText(ActionListener):
        def __init__(self, app, bufinput):
            self.buf = bufinput
            self.app = app
        
        def actionPerformed(self, act):
            if not self.buf.ready():
                return
            pp = self.buf.readLine()
            if pp:
                self.app.sendTextToMU(pp)

                
    class SendLine(ActionListener):
        def __init__(self, input, outt):
            self.input = input
            self.outt = outt
        
        def actionPerformed(self, act):
            pp = self.input.getText()
            self.input.setText("")
            self.outt.println(pp)

    class SendLineFromMq(MessageListener):
        def __init__(self, outt):
            self.outt = outt

        def onMessage(self, m):
            self.outt.println(m.text)
            
    def sendTextToMU(self, te):
        mm = self.ansiRegEx.matcher(te)
        curstyle = self.doc.getStyle("regular")
        start = 0
        while mm.find():
            self.doc.insertString(self.doc.getLength(), te[start:mm.start()], curstyle)
            codes = te[mm.start()+2:mm.end()-1]
            for code in codes.split(';'):
                if code == '0':
                    curstyle = self.doc.getStyle("regular")
                if code == '1':
                    curstyle = self.doc.getStyle("bold")
                if code == '3' or code == '5':
                    curstyle = self.doc.getStyle("italic")
                if code == '5' or code == '4':
                    curstyle = self.doc.getStyle("underline")
                if len(code) == 2 and code[0] == '3':
                    ## Color codes.   Not implemented
                    pass
            start = mm.end()
        self.doc.insertString(self.doc.getLength(), te[start:], curstyle)
        self.doc.insertString(self.doc.getLength(), "\n", curstyle)
        
        self.outputScrollPane.getHorizontalScrollBar().setValue(self.outputScrollPane.getHorizontalScrollBar().getMaximum())
        
    def initDocumentStyles(self):
        
        deff = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
        

        ss = self.doc.addStyle("regular", deff )
        #s = Style()
        StyleConstants.setFontFamily(ss, "Courier New")
        StyleConstants.setFontSize(ss, 12)
        
        s = self.doc.addStyle("bold", ss)
        StyleConstants.setBold(s, True)
        s = self.doc.addStyle("italic", ss)
        StyleConstants.setItalic(s, True)
        s = self.doc.addStyle("underline", ss)
        StyleConstants.setUnderline(s, True)
        
    
    def initGUI(self, frame):
        
        ## Setup Initial Frame work
        self.frame = frame
        self.wl = SwingTest.TelWindowListener(self)
        self.frame.addInternalFrameListener(self.wl)
        
        ## Setup Output frame
        self.output = JTextPane()
        self.output.setEditable(False)
        self.doc = self.output.getStyledDocument()
        self.initDocumentStyles()
        
        ## Setup Scroll-bars for the Output Pane
        self.outputScrollPane = JScrollPane(self.output)
        self.outputScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS)
        self.outputScrollPane.setMinimumSize(Dimension(200,200))
        self.outputScrollPane.setMaximumSize(Dimension(400,400))

        ## Setup Input Panel
        self.input = JTextField()

        ## Add stuff to the Frame
        self.frame.getContentPane().add(self.outputScrollPane, BorderLayout.CENTER)
        self.frame.getContentPane().add(self.input, BorderLayout.PAGE_END)
        
        ## Back the frame and maximize.
        self.frame.pack()
        self.frame.setMaximum(True)

    def __init__(self, frame):
        '''
        Constructor
        '''

        ## Initialize class variables.
        self.sock = None
        self.telnetchetimer = None
        self.thinknetLoaded = False
        
        ##  Compile the RegEx to use for ANSI support 
        self.ansiRegEx = Pattern.compile("(\x1b\[[0-9;]+m)")
        
        ## Create a GUID / UUID for this instance 
        self.instanceGUID =  UUID.randomUUID().toString()
        
        self.initGUI(frame)
        
        ## Deal with properties from applet
        if(not applet.getProperty("host") or not applet.getProperty("port")):
            self.output.setText("No 'host' or 'port' was specified for the Applet")
        else:        
            self.host = applet.getProperty("host")
            self.port = int(applet.getProperty("port"))
            
            if(not applet.getProperty("sitename")):
                self.sitename = self.host + ":" + str(self.port)
            else:
                self.sitename = applet.getProperty("sitename")  
            
            self.connect()

    def loadThinknetPanel(self):
        global applet
        global mq
        
        if not self.thinknetLoaded:
            self.thinknetChannel = "thinknet-%s" % self.instanceGUID
            
            self.mqhandle = SwingTest.SendLineFromMq(self.out)
            mq.subscribe(self.thinknetChannel, self.mqhandle)
           
            tm = Map()
            tm["jms-url"] = applet.getProperty("jms-url")
            tm["jms-channel"] = self.thinknetChannel
            applet.runApplet("thinknet.xml", tm);
            
            self.thinknetLoaded = True
        
          
    def connect(self):
        
        ## Create the socket
        try:
            self.sock = Socket(self.host,self.port)
        except Exception, e:
            print e
        
        ## Setup Input and Output for the socket
        self.inn = BufferedReader(InputStreamReader(self.sock.getInputStream())) 
        self.out = PrintStream(self.sock.getOutputStream())
        self.telhandle = SwingTest.SendText(self,self.inn)
        self.outhandle = SwingTest.SendLine(self.input, self.out)
        self.input.addActionListener(self.outhandle)
        
        ## Setup a timer to poll the socket
        self.telnetchetimer = Timer(10, self.telhandle)
        self.telnetchetimer.start()        
        self.frame.title = "Connected to " + self.sitename

        


c = SwingTest(frame)